#include "qterminalwidget.h"

QTerminalWidget::QTerminalWidget(QWidget *parent) :
    QWidget(parent)
{
  init();
}

void QTerminalWidget::dataIn(QByteArray datain)
{
  // Handle ASCII
  QString dispdata = QString(datain);

  // Handle HEX

  QByteArray hexarray=dispdata.toAscii().toHex();
  for(int i=2;i<hexarray.size();i+=2)
  {
    hexarray.insert(i,' ');
    i++;
  }
  hexarray.append(" \n");

  // Display
  if(updateCheck->isChecked())
  {
    QTextCharFormat tf;
    tf = asciiLog->currentCharFormat();
    tf.setForeground(QBrush(Qt::red));
    asciiLog->moveCursor(QTextCursor::End);
    asciiLog->setCurrentCharFormat(tf);
    asciiLog->insertPlainText(dispdata);
    asciiLog->moveCursor(QTextCursor::End);

    tf = hexLog->currentCharFormat();
    tf.setForeground(QBrush(Qt::red));
    hexLog->moveCursor(QTextCursor::End);
    hexLog->setCurrentCharFormat(tf);
    hexLog->insertPlainText(QString(hexarray));
    hexLog->moveCursor(QTextCursor::End);
  }

}

void QTerminalWidget::datatoServer(QString edit)
{
    QByteArray payload;
    payload.append(edit);

    // Handle HEX
    QByteArray hexarray=edit.toAscii().toHex();
    for(int i=2;i<hexarray.size();i+=2)
    {
      hexarray.insert(i,' ');
      i++;
    }
    hexarray.append(' ');

    if(updateCheck->isChecked())
    {
      QTextCharFormat tf;
      tf = asciiLog->currentCharFormat();
      tf.setForeground(QBrush(Qt::blue));
      asciiLog->moveCursor(QTextCursor::End);
      asciiLog->setCurrentCharFormat(tf);
      asciiLog->insertPlainText(edit);
      asciiLog->moveCursor(QTextCursor::End);
      tf.setForeground(QBrush(Qt::red));
      tf = asciiLog->currentCharFormat();

      tf = hexLog->currentCharFormat();
      tf.setForeground(QBrush(Qt::blue));
      hexLog->moveCursor(QTextCursor::End);
      hexLog->setCurrentCharFormat(tf);
      hexLog->insertPlainText(QString(hexarray));
      hexLog->moveCursor(QTextCursor::End);
      tf.setForeground(QBrush(Qt::red));
      tf = hexLog->currentCharFormat();
    }
  disconnect(liveEdit,SIGNAL(textChanged(QString)),this,SLOT(datatoServer(QString)));
  liveEdit->clear();
  connect(liveEdit,SIGNAL(textChanged(QString)),this,SLOT(datatoServer(QString)));

  emit dataOut(payload);
}

void QTerminalWidget::togglehexPacket(bool hexmode)
{
  QString packetString;
  packetString = packetEdit->text();
  if(hexmode)
  {
    QByteArray hexArray = packetString.toAscii().toHex();
    for(int i=2;i<hexArray.size();i+=2)
    {
      hexArray.insert(i,' ');
      i++;
    }
    disconnect(packetEdit,SIGNAL(textChanged(QString)),this,SLOT(packetModified(QString)));
    packetEdit->setText(hexArray);
    connect(packetEdit,SIGNAL(textChanged(QString)),this,SLOT(packetModified(QString)));
  }
  else
  {
    QByteArray tempArray;
    tempArray.append(packetString);
    QByteArray hexArray = QByteArray::fromHex(tempArray);
    disconnect(packetEdit,SIGNAL(textChanged(QString)),this,SLOT(packetModified(QString)));
    packetEdit->setText(hexArray);
    connect(packetEdit,SIGNAL(textChanged(QString)),this,SLOT(packetModified(QString)));
  }
}

void QTerminalWidget::packetModified(QString newPacket)
{
  QString tempstring = newPacket;
  int editpos = packetEdit->cursorPosition();
  // Analyze new packet, remove non-hex/space characters
  if(hexCheck->isChecked())
  {
    tempstring.clear();
    for(int i=0;i<newPacket.size();i++)
    {
      if((newPacket.at(i)==' ' || newPacket.at(i).isDigit() ||\
          (newPacket.at(i)>='a' && newPacket.at(i)<='f') ||\
          (newPacket.at(i)>='A' && newPacket.at(i)<='F')))
      {
        tempstring.append(newPacket.at(i));
      }
      else editpos--;
    }
    disconnect(packetEdit,SIGNAL(textChanged(QString)),this,SLOT(packetModified(QString)));
    packetEdit->setText(tempstring);
    connect(packetEdit,SIGNAL(textChanged(QString)),this,SLOT(packetModified(QString)));
    packetEdit->setCursorPosition(editpos);
  }
}

void QTerminalWidget::sendPacket()
{
  // Build byte array:
  QByteArray hexArray;
  if(hexCheck->isChecked())
  {
    QByteArray tempArray;
    tempArray.append(packetEdit->text());
    hexArray = QByteArray::fromHex(tempArray);
  }
  else hexArray.append(packetEdit->text());

  datatoServer(QString(hexArray));
}

void QTerminalWidget::clearTerminal()
{
  asciiLog->clear();
  hexLog->clear();
}

void QTerminalWidget::init()
{
  // COMM OBJECTS
 settingsLayout =  new QVBoxLayout;
liveLayout =  new QHBoxLayout;
packetLayout = new QHBoxLayout;
packetSettingsLayout = new QHBoxLayout;
displaySettingsLayout = new QHBoxLayout;
liveBox = new QGroupBox("Live");
liveBox->setAlignment(Qt::AlignHCenter);
liveBox->setMaximumSize(300,50);
liveEdit = new QLineEdit;
packetBox = new QGroupBox("Packet");
packetBox->setAlignment(Qt::AlignHCenter);
packetBox->setMaximumSize(300,140);
packetEdit = new QLineEdit;
hexCheck = new QCheckBox("Hex");
displayBox = new QGroupBox("Display");
displayBox->setAlignment(Qt::AlignHCenter);
displayBox->setMaximumSize(300,60);
sendButton = new QPushButton("Send");
updateCheck = new QCheckBox("Update");
updateCheck->setChecked(true);
clearButton = new QPushButton("Clear");

QVBoxLayout *liveBoxLayout = new QVBoxLayout;
liveBoxLayout->setSpacing(0);
liveBoxLayout->setContentsMargins(2,2,2,2);
liveLayout->addSpacing(10);
liveLayout->addWidget(liveEdit);
liveLayout->addSpacing(10);
liveBoxLayout->addLayout(liveLayout);
liveBox->setLayout(liveBoxLayout);

QVBoxLayout *packetBoxLayout = new QVBoxLayout;
packetBoxLayout->setSpacing(2);
packetBoxLayout->setContentsMargins(2,2,2,2);
packetLayout->addSpacing(10);
packetLayout->addWidget(packetEdit);
packetLayout->addSpacing(10);
packetBoxLayout->addLayout(packetLayout);
packetSettingsLayout->addStretch(1);
packetSettingsLayout->addWidget(hexCheck);
packetSettingsLayout->addWidget(sendButton);
packetSettingsLayout->addStretch(1);
packetBoxLayout->addLayout(packetSettingsLayout);
packetBox->setLayout(packetBoxLayout);

displaySettingsLayout->setSpacing(0);
displaySettingsLayout->setContentsMargins(0,0,0,0);
displaySettingsLayout->addStretch(1);
displaySettingsLayout->addWidget(updateCheck);
displaySettingsLayout->addWidget(clearButton);
displaySettingsLayout->addStretch(1);
displayBox->setLayout(displaySettingsLayout);

settingsLayout->setSpacing(2);
settingsLayout->setContentsMargins(0,0,0,0);
settingsLayout->addWidget(liveBox);
settingsLayout->addWidget(packetBox);
settingsLayout->addWidget(displayBox);

  // DISPLAY OBJECTS
displayLayout = new QVBoxLayout;
asciiLog = new QPlainTextEdit;
asciiLog->setMinimumWidth(100);
asciiLog->setMaximumBlockCount(10);
hexLog = new QPlainTextEdit;
hexLog->setMinimumWidth(100);
hexLog->setMaximumBlockCount(10);
displayLayout->addWidget(asciiLog);
displayLayout->addWidget(hexLog);

// LAYOUTS
mainLayout = new QHBoxLayout;
mainLayout->addLayout(settingsLayout);
mainLayout->addLayout(displayLayout);

this->setLayout(mainLayout);

// CONNECTIONS
connect(liveEdit,SIGNAL(textChanged(QString)),this,SLOT(datatoServer(QString)));
connect(hexCheck,SIGNAL(toggled(bool)),this,SLOT(togglehexPacket(bool)));
connect(packetEdit,SIGNAL(textChanged(QString)),this,SLOT(packetModified(QString)));
connect(sendButton,SIGNAL(clicked()),this,SLOT(sendPacket()));
connect(clearButton,SIGNAL(clicked()),this,SLOT(clearTerminal()));

}
